package MyFramePro.Service.Impl;

import MyFramePro.Constants.SystemConstants;
import MyFramePro.Domain.Entity.Menu;
import MyFramePro.Domain.Entity.Role;
import MyFramePro.Domain.Entity.RoleMenu;
import MyFramePro.Domain.Entity.UserRole;
import MyFramePro.Domain.ResponseResult;
import MyFramePro.Domain.Vo.ChangeRoleStatusVo;
import MyFramePro.Domain.Vo.PageVo;
import MyFramePro.Domain.Vo.RoleVo;
import MyFramePro.Enums.AppHttpCodeEnum;
import MyFramePro.Mapper.RoleMapper;
import MyFramePro.Mapper.UserRoleMapper;
import MyFramePro.Service.RoleService;
import MyFramePro.Utils.BeanCopyUtils;
import MyFramePro.Utils.SecurityUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private RoleServiceImpl roleService;

    @Resource
    private RoleMenuServiceImpl roleMenuService;

    /**
     *  根据用户 id 查询对应的角色信息
     */
    @Override
    public List<String> selectRoleKeyByUserId(Long id) {
        //1.如果是管理员，则直接返回 admin
        ArrayList<String> list = new ArrayList<>();
        if (id==1L){
            list.add("admin");
            return list;
        }

//        //2.根据对应的用户 userID ，获取到对应的角色 roleID
//        LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(UserRole::getUserId,id);
//        List<UserRole> rolesId = userRoleMapper.selectList(queryWrapper);
//
//        //3.通过角色 roleId 获取到对应的 roleKey，并保存到集合中进行返回
//        ArrayList<String> roleKeys = new ArrayList<>();
//        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
//        rolesId.stream()
//               .map(userRole -> userRole.getRoleId())
//                .forEach(roleId -> {
//                   Role role = roleMapper.selectById(roleId);
//                   roleKeys.add(role.getRoleKey());
//               });

        //2.否则查询用户所具有的角色信息
        return roleMapper.selectRoleKeyByUserId(id);    //这里使用 SQL 语句进行查询

    }


    /**
     * 这里是查询用户列表的功能
     */
    @Override
    public ResponseResult getRoleList(Integer pageNum, Integer pageSize, String roleName, String status) {

        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        //1.进行条件过滤
        //1.1若查询信息中没有状态信息，则默认查询正常状态下的角色
        if (StringUtils.hasText(status)){

            wrapper.eq(Role::getStatus,status);
        }else {
            wrapper.eq(Role::getStatus,SystemConstants.ROLE_STATUS);
        }
        //1.2针对角色名称进行模糊查询
        wrapper.like(StringUtils.hasText(roleName),Role::getRoleName,roleName);
        //1.3按照role_sort进行升序排列
        wrapper.orderByAsc(Role::getRoleSort);

        //2.进行分页查询
        Page<Role> rolePage = new Page<>(pageNum,pageSize);
        roleService.page(rolePage,wrapper);
        //2.1获取分页查询的数据
        List<Role> roleList = rolePage.getRecords();

        //3.由于前端字段的需求，这里转换为 Vo 类型的对象
        List<RoleVo> roleVos = BeanCopyUtils.myCopyBeanList(roleList, RoleVo.class);    //一转

        PageVo pageVo = new PageVo(roleVos, rolePage.getTotal());   //二转

        return ResponseResult.okResult(pageVo);
    }


    /**
     * 这里是改变角色状态的功能
     */
    @Override
    public ResponseResult changeRoleStatus(ChangeRoleStatusVo roleStatusVo) {

        LambdaUpdateWrapper<Role> updateWrapper = new LambdaUpdateWrapper<>();

        updateWrapper.set(Role::getStatus,roleStatusVo.getStatus());
        updateWrapper.eq(Role::getId,roleStatusVo.getRoleid());

        roleService.update(updateWrapper);

        return ResponseResult.okResult();
    }


    /**
     * 这里是新增角色的功能
     */
    @Override
    public ResponseResult addRole(RoleVo roleVo) {

        //1.添加角色信息
        Role role = BeanCopyUtils.myCopyBean(roleVo, Role.class);

        roleService.save(role);

        //2.将角色信息与菜单信息相关联
        List<RoleMenu> roleMenuList = roleVo.getMenuIds().stream()
                .map(new Function<Long, RoleMenu>() {
                    @Override
                    public RoleMenu apply(Long menuId) {

                        return new RoleMenu(role.getId(), menuId);  //这里将角色 ID 与菜单 ID 关联
                    }
                }).collect(Collectors.toList());

        roleMenuService.saveBatch(roleMenuList);

        return ResponseResult.okResult();
    }


    /**
     * 修改角色之角色信息回显
     */
    @Override
    public ResponseResult showRoleInfo(Long id) {

        //1.根据 ID 查询当前的角色信息
        Role role = roleService.getById(id);

        RoleVo roleVo = BeanCopyUtils.myCopyBean(role, RoleVo.class);


        return ResponseResult.okResult(roleVo);
    }


    /**
     * 这里是更新角色信息的功能
     */
    @Override
    public ResponseResult updateRole(RoleVo roleVo) {

        //1.先更新对应的角色信息
        Role role = BeanCopyUtils.myCopyBean(roleVo, Role.class);
        roleService.updateById(role);

        //2.然后再跟新对应的菜单与角色相关联的信息
        //2.1删除之前的关联信息
        LambdaQueryWrapper<RoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RoleMenu::getRoleId,roleVo.getId());
        roleMenuService.remove(queryWrapper);
        //2.2保存当前的关联信息
        List<RoleMenu> roleMenuList = roleVo.getMenuIds().stream()
                .map(new Function<Long, RoleMenu>() {
                    @Override
                    public RoleMenu apply(Long menuId) {

                        return new RoleMenu(roleVo.getId(), menuId);
                    }
                }).collect(Collectors.toList());

        roleMenuService.saveBatch(roleMenuList);

        return ResponseResult.okResult();
    }


    /**
     * 这里是删除角色的功能
     */
    @Override
    public ResponseResult deleteRole(Long roleId) {

        roleService.removeById(roleId);

        return ResponseResult.okResult();
    }


    /**
     * 新增用户————查询角色信息的功能
     */
    @Override
    public ResponseResult selectAllRoles() {

        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        //1.查询所有状态正常的角色
        queryWrapper.eq(Role::getStatus,SystemConstants.ROLE_STATUS);

        List<Role> roleList = roleService.list(queryWrapper);

        return ResponseResult.okResult(roleList);
    }


}
